package com.example.charges.dati.domain.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.Observable;
import java.util.Vector;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.example.charges.AltreUtil;
import com.example.charges.ControllerCharge;
import com.example.charges.dati.domain.CatSpese;
import com.example.charges.dati.domain.Entrate;
import com.example.charges.dati.domain.ISingleSpesa;
import com.example.charges.dati.domain.SingleSpesa;
import com.example.charges.dati.domain.Utenti;
import com.example.charges.dati.domain.cache.CacheCategorie;
import com.example.charges.dati.domain.cache.CacheUtenti;
import com.molinari.androidstructure.data.db.IDao;
import com.molinari.androidstructure.data.db.IOggettoEntita;
import com.molinari.androidstructure.data.db.UtilDb;
import com.molinari.jdbcandroid.wrap.ConnectionAndroid;

public class WrapSingleSpesa extends Observable implements IDao, ISingleSpesa {

	private final SingleSpesa uscita;
	private final Context context;

	public WrapSingleSpesa(Context context) {
		uscita = new SingleSpesa();
		this.context = context;
	}

	public WrapSingleSpesa(final SingleSpesa spesa, Context context) {
		this.uscita = spesa;
		this.context = context;
	}

	@Override
	public Object selectById(final int id) {
		SingleSpesa uscita = null;
		try {
			final Connection cn = ControllerCharge.getConnection(context);
			final ConnectionAndroid cnAndroid = (ConnectionAndroid) cn;
			final String[] idUscitaString = new String[] { Integer.toString(id) };
			final String orderBy = SingleSpesa.DATA + " desc";
			final Cursor rs = cnAndroid.getDb().query(SingleSpesa.NOME_TABELLA, null, SingleSpesa.ID, idUscitaString, null, null, orderBy);
			if (rs.moveToFirst()) {
				do {
					uscita = new SingleSpesa();
					final Utenti utente = CacheUtenti.getSingleton().getUtente(context, Integer.toString(rs.getInt(7)));
					final CatSpese cat = CacheCategorie.getSingleton().getCatSpese(context, Integer.toString(5));
					setUscitaFromCursor(utente, cat, rs, uscita);
				} while (rs.moveToNext());
			}
			if (rs != null && !rs.isClosed()) {
				rs.close();
			}
			cnAndroid.close();
		} catch (Exception e) {
			Log.e(e.getClass().getName(), Log.getStackTraceString(e));
		}
		return uscita;
	}

	private void setUscitaFromCursor(final Utenti utente, final CatSpese categoria, final Cursor rs, final SingleSpesa uscita) {
		uscita.setidSpesa(UtilDb.getInt(rs, SingleSpesa.ID));
		uscita.setData(UtilDb.getString(rs, SingleSpesa.DATA));
		uscita.setinEuro(UtilDb.getDouble(rs, SingleSpesa.INEURO));
		uscita.setdescrizione(UtilDb.getString(rs, SingleSpesa.DESCRIZIONE));
		uscita.setCatSpese(categoria);
		uscita.setnome(UtilDb.getString(rs, SingleSpesa.NOME));
		uscita.setUtenti(utente);
		uscita.setDataIns(UtilDb.getString(rs, SingleSpesa.DATAINS));
	}

	@Override
	public Iterator<Object> selectWhere(final String where) {
		// TODO Auto-generated method stub
		return null;
	}

	public Vector<Object> selectAllForUtente() throws android.database.SQLException, SQLException {
		final Vector<Object> uscite = new Vector<Object>();
		final Utenti utente = ControllerCharge.getSingleton().getUtenteLogin();
		final Connection cn = ControllerCharge.getConnection(context);
		ConnectionAndroid cnAndroid = (ConnectionAndroid) cn;

		final Cursor cursor = cnAndroid.getDb().query(SingleSpesa.NOME_TABELLA, null, null, null, null, null, SingleSpesa.DATA + " desc");

		if (cursor.moveToFirst()) {
			do {
				final SingleSpesa uscita = new SingleSpesa();
				final CatSpese cat = CacheCategorie.getSingleton().getCatSpese(context, Integer.toString(5));
				setUscitaFromCursor(utente, cat, cursor, uscita);
				uscite.add(uscita);
			} while (cursor.moveToNext());
		}
		if (cursor != null && !cursor.isClosed()) {
			cursor.close();
		}
		ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		return uscite;

	}

	public static void main(final String[] args) {
		//		final WrapSingleSpesa wrap = new WrapSingleSpesa();
		//		wrap.selectAll();
	}

	@Override
	public Iterator<Object> selectAll() {
		final Vector<Object> uscite = new Vector<Object>();
		final Connection cn = ControllerCharge.getConnection(context);
		final ConnectionAndroid cnAndroid = (ConnectionAndroid) cn;
		String orderBy = SingleSpesa.DATA + " desc";
		Cursor cursor = cnAndroid.getDb().query(SingleSpesa.NOME_TABELLA, null, null, null, null, null, orderBy);
		if (cursor.moveToFirst()) {
			do {
				int idUt = UtilDb.getInt(cursor, SingleSpesa.IDUTENTE);
				String idUtente = Integer.toString(idUt);
				final Utenti utente = idUt != 0 ? CacheUtenti.getSingleton().getUtente(context, idUtente) : null;
				int idCategoria = UtilDb.getInt(cursor, SingleSpesa.IDCATEGORIE);
				String idCat = Integer.toString(idCategoria);
				final CatSpese cat = idCategoria != 0 ? CacheCategorie.getSingleton().getCatSpese(context, idCat) : null;

				final SingleSpesa uscita = new SingleSpesa();
				setUscitaFromCursor(utente, cat, cursor, uscita);
				uscite.add(uscita);
				
			} while (cursor.moveToNext());
		}
		try {
			ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		} catch (android.database.SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		} catch (SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		}
		return uscite != null ? uscite.iterator() : null;
	}
	
	@Override
	public boolean insert(final Object oggettoEntita) {

		final ConnectionAndroid cnAndroid = (ConnectionAndroid) ControllerCharge.getConnection(context);;
		final SQLiteDatabase db = cnAndroid.getDb();

		final SingleSpesa uscita = (SingleSpesa) oggettoEntita;

		ContentValues values = new ContentValues();
		values.put(SingleSpesa.DATA, uscita.getData());
		values.put(SingleSpesa.INEURO, uscita.getinEuro());
		values.put(SingleSpesa.DESCRIZIONE, uscita.getdescrizione());

		if (uscita.getCatSpese() != null) {
			values.put(SingleSpesa.IDCATEGORIE, uscita.getCatSpese().getidCategoria());
		}
		values.put(SingleSpesa.NOME, uscita.getNomeEntita());
		if (uscita.getUtenti() != null) {
			values.put(SingleSpesa.IDUTENTE, uscita.getUtenti().getidUtente());
		}
		values.put(SingleSpesa.DATAINS, uscita.getDataIns());
		if (db.insert(SingleSpesa.NOME_TABELLA, null, values) == -1) {
			return false;
		}

		try {
			ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		} catch (android.database.SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		} catch (SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		}
		return true;

	}

	@Override
	public boolean delete(final int id) {
		ConnectionAndroid cnAndroid = (ConnectionAndroid) ControllerCharge.getConnection(context);;
		final SQLiteDatabase db = cnAndroid.getDb();
		String[] idUscite = new String[] { Integer.toString(id) };

		if (db.delete(SingleSpesa.NOME_TABELLA, SingleSpesa.ID + " = ?", idUscite) == 0) {
			return false;
		}

		try {
			ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		} catch (android.database.SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		} catch (SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		}

		return true;
	}

	@Override
	public boolean update(final Object oggettoEntita) {
		ConnectionAndroid cnAndroid = (ConnectionAndroid) ControllerCharge.getConnection(context);;
		final SingleSpesa uscita = (SingleSpesa) oggettoEntita;
		final SQLiteDatabase db = cnAndroid.getDb();
		final ContentValues args = new ContentValues();
		args.put(SingleSpesa.DESCRIZIONE, uscita.getdescrizione());
		args.put(SingleSpesa.IDCATEGORIE, uscita.getCatSpese() != null ? uscita.getCatSpese().getidCategoria() : null);
		args.put(SingleSpesa.INEURO, uscita.getinEuro());
		args.put(SingleSpesa.DATA, uscita.getData());
		args.put(SingleSpesa.NOME, uscita.getNomeEntita());
		args.put(SingleSpesa.IDUTENTE, uscita.getUtenti() != null ? uscita.getUtenti().getidUtente() : 0);
		args.put(SingleSpesa.DATAINS, uscita.getDataIns());

		if (db.update(SingleSpesa.NOME_TABELLA, args, SingleSpesa.ID + " = " + uscita.getIdEntita(), null) == -1) {
			return false;
		}

		try {
			ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		} catch (android.database.SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		} catch (SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		}
		return true;
	}

	@Override
	public boolean deleteAll() {
		ConnectionAndroid cnAndroid = (ConnectionAndroid) ControllerCharge.getConnection(context);;
		final SQLiteDatabase db = cnAndroid.getDb();

		if (db.delete(Entrate.NOME_TABELLA, "1", null) == -1) {
			return false;
		}

		try {
			ControllerCharge.getSingleton().getConnectionPool(context).chiudiOggettiDb(cnAndroid);
		} catch (android.database.SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		} catch (SQLException e) {
			Log.e(WrapSingleSpesa.class.getName(), Log.getStackTraceString(e));
		}
		return true;
	}

	/**
	 * Permette di ottenere un vettore con un numero di entita' SingleSpesa
	 * inserito come parametro
	 * 
	 * @param dieci
	 * @return Vector<SingleSpesa>
	 */
	public Vector<SingleSpesa> movimentiUsciteFiltrate(final String dataDa, final String dataA, final String nome, final Double euro, final String catSpese) {
		Vector<SingleSpesa> sSpesa = null;

		final Utenti utente = ControllerCharge.getSingleton().getUtenteLogin();
		int idUtente = 0;
		if (utente != null) {
			idUtente = utente.getidUtente();
		}

		final StringBuffer sql = new StringBuffer();
		sql.append("SELECT * FROM " + SingleSpesa.NOME_TABELLA + " WHERE " + SingleSpesa.IDUTENTE + " = " + idUtente);
		if (AltreUtil.checkData(dataDa, "/") && AltreUtil.checkData(dataA, "/") && dataDa != null && dataA != null) {
			sql.append(" AND " + SingleSpesa.DATA + " BETWEEN '" + dataDa + "'" + " AND '" + dataA + "'");
		} else if (AltreUtil.checkData(dataDa, "/") && dataDa != null) {
			sql.append(" AND " + SingleSpesa.DATA + " = '" + dataDa + "'");
		}
		if (nome != null) {
			sql.append(" AND " + SingleSpesa.NOME + " = '" + nome + "'");
		}
		if (euro != null) {
			sql.append(" AND " + SingleSpesa.INEURO + " = " + euro);
		}
		if (catSpese != null && Integer.parseInt(catSpese) != 0) {
			sql.append(" AND " + SingleSpesa.IDCATEGORIE + " = " + Integer.parseInt(catSpese));
		}
		final Connection cn = ControllerCharge.getConnection(context);

		try {
			final Statement st = cn.createStatement();
			final ResultSet rs = st.executeQuery(sql.toString());
			sSpesa = new Vector<SingleSpesa>();
			while (rs.next()) {
				final CatSpese categoria = CacheCategorie.getSingleton().getCatSpese(context, rs.getString(5));
				final SingleSpesa ss = new SingleSpesa();
				ss.setidSpesa(rs.getInt(1));
				ss.setData(rs.getString(2));
				ss.setinEuro(rs.getDouble(3));
				ss.setdescrizione(rs.getString(4));
				ss.setnome(rs.getString(6));
				ss.setCatSpese(categoria);
				ss.setDataIns(rs.getString(8));
				ss.setUtenti(utente);
				sSpesa.add(ss);
			}
		} catch (final SQLException e) {
			// Controllore.getLog().severe(LoggerOggetto.getMessaggioErroreOperazione(e));
			e.printStackTrace();
		}
		try {
			cn.close();
		} catch (final SQLException e) {
			e.printStackTrace();
		}
		
		return sSpesa;

	}

	/**
	 * Permette di ottenere un vettore con un numero di entita' SingleSpesa
	 * inserito come parametro
	 * 
	 * @param dieci
	 * @return Vector<SingleSpesa>
	 */
	public Vector<SingleSpesa> dieciUscite(final int dieci) {
		Vector<SingleSpesa> sSpesa = null;

		final Utenti utente = ControllerCharge.getSingleton().getUtenteLogin();
		int idUtente = 0;
		if (utente != null) {
			idUtente = utente.getidUtente();
		}

		final String sql = "select * from " + SingleSpesa.NOME_TABELLA + " where " + SingleSpesa.DATA + " BETWEEN '" 
				+ ControllerCharge.getSingleton().getAnnoRif() + "/01/01'" + " AND '" 
				+ ControllerCharge.getSingleton().getAnnoRif() + "/12/31'"
				+ " AND " + SingleSpesa.IDUTENTE + " = " + idUtente + " ORDER BY " 
				+ SingleSpesa.ID + " desc limit 0," + dieci;
		final Connection cn = ControllerCharge.getConnection(context);

		try {
			final Statement st = cn.createStatement();
			final ResultSet rs = st.executeQuery(sql);
			sSpesa = new Vector<SingleSpesa>();
			while (rs.next()) {
				final CatSpese categoria = CacheCategorie.getSingleton().getCatSpese(context, rs.getString(5));
				final SingleSpesa ss = new SingleSpesa();
				ss.setidSpesa(rs.getInt(1));
				ss.setData(rs.getString(2));
				ss.setinEuro(rs.getDouble(3));
				ss.setdescrizione(rs.getString(4));
				ss.setnome(rs.getString(6));
				ss.setCatSpese(categoria);
				ss.setDataIns(rs.getString(8));
				ss.setUtenti(utente);
				sSpesa.add(ss);
			}
		} catch (final SQLException e) {
			// TODO implementare log
			// log.severe("Impossibile caricare il record da single_spesa: "+e.getMessage());
			e.printStackTrace();
		}
		try {
			cn.close();
		} catch (final SQLException e) {
			e.printStackTrace();
		}
		
		return sSpesa;

	}

	/**
	 * Cancella l'ultima entita' "SingleSpesa" inserita
	 */
	public boolean deleteLastSpesa() {
		boolean ok = false;
		final Connection cn = ControllerCharge.getConnection(context); 
		final String sql = "SELECT * FROM " + SingleSpesa.NOME_TABELLA + " WHERE " + Entrate.IDUTENTE + " = " + ControllerCharge.getSingleton().getUtenteLogin().getidUtente() + " ORDER BY " + SingleSpesa.DATAINS
				+ " DESC";

		try {
			final Statement st = cn.createStatement();
			final ResultSet rs = st.executeQuery(sql);
			if (rs.next()) {
				SingleSpesa ss = new SingleSpesa();
				ss = new SingleSpesa();
				ss.setidSpesa(rs.getInt(1));

				final String sql2 = "DELETE FROM " + SingleSpesa.NOME_TABELLA + " WHERE " + SingleSpesa.ID + "=?";
				final PreparedStatement ps = cn.prepareStatement(sql2);
				ps.setInt(1, ss.getidSpesa());
				ps.executeUpdate();
				ok = true;
			} else {
				// Alert.operazioniSegnalazioneErroreWarning("Non ci sono uscite per l'utente loggato");
			}

		} catch (final Exception e) {
			e.printStackTrace();
			// Controllore.getLog().severe(LoggerOggetto.getMessaggioErroreOperazione(e));
		}
		try {
			cn.close();
		} catch (final SQLException e) {
			e.printStackTrace();
		}
		
		return ok;
	}

	@Override
	public String getData() {
		return uscita.getData();
	}

	@Override
	public void setData(final String Data) {
		uscita.setData(Data);
	}

	@Override
	public String getdescrizione() {
		return uscita.getdescrizione();
	}

	@Override
	public void setdescrizione(final String descrizione) {
		uscita.setdescrizione(descrizione);
	}

	@Override
	public int getidSpesa() {
		return uscita.getidSpesa();
	}

	@Override
	public void setidSpesa(final int idSpesa) {
		uscita.setidSpesa(idSpesa);
	}

	@Override
	public double getinEuro() {
		return uscita.getinEuro();
	}

	@Override
	public void setinEuro(final double d) {
		uscita.setinEuro(d);
	}

	@Override
	public String getNomeEntita() {
		return uscita.getNomeEntita();
	}

	@Override
	public void setnome(final String nome) {
		uscita.setnome(nome);
	}

	@Override
	public CatSpese getCatSpese() {
		return uscita.getCatSpese();
	}

	@Override
	public void setCatSpese(final CatSpese catSpese) {
		uscita.setCatSpese(catSpese);
	}

	@Override
	public Utenti getUtenti() {
		return uscita.getUtenti();
	}

	@Override
	public void setUtenti(final Utenti utenti) {
		uscita.setUtenti(utenti);
	}

	@Override
	public void setDataIns(final String dataIns) {
		uscita.setDataIns(dataIns);
	}

	@Override
	public String getDataIns() {
		return uscita.getDataIns();
	}

	@Override
	public IOggettoEntita getEntitaPadre() {
		return uscita;
	}

	@Override
	public void notifyObservers() {
		super.notifyObservers();
	}

	@Override
	protected synchronized void setChanged() {
		super.setChanged();
	}

	@Override
	public IOggettoEntita getEntita() {
		return getEntitaPadre();
	}

}
